# coding=utf-8
"""
    转 gcp / edc :
"""
import json

import openpyxl
from openpyxl.utils.exceptions import InvalidFileException

# from urllib.parse import parse_qs
# from utils.api_class_conf import token_fixture
from utils.curl_convert import curl_to_table_data


# @Time    :  2024-08-29 18:57:42
# @Author  :  jiangtong
# @Email   :  gingerqgyy@outlook.com
# @Project :  test_curl_convert
# @File    :  convert_to


# curl 转 gcp :
def convert2gcp(curl_command, sheet_name=None, case_id=None, api_name=None, model=None, title=None):
    """
    根据 curl_command 转换脚本
    :param curl_command: curl 命令
    :param sheet_name: Sheet 页
    :param case_id: 用例编号
    :param api_name: 接口名
    :param model: 用例模块
    :param title: 用例标题
    :return:
    """

    # 解析 curl 命令, curl 转 table_data
    _req_data = curl_to_table_data(curl_command)

    # 取 table_data 的数据 :
    host = _req_data.host
    url = _req_data.uri
    headers = _req_data.headers
    method = _req_data.method
    data = _req_data.params_data
    _terminal = headers.get('terminal', 'WEBPC')

    # Excel data :
    sheet_name = sheet_name if sheet_name else 'Sheet页'
    case_id = case_id if case_id else '编号'
    api_name = api_name if api_name else '接口名称'
    model = model if model else '模块'
    title = title if title else '用例名'

    # 处理 data :
    data = _req_data.data if _req_data.data else data
    try:
        data = json.dumps(data)
    except json.JSONDecodeError:
        data = str(_req_data.data)

    # 处理 url 最后的 id :
    uri_id = ','
    if _req_data.uri_id:
        uri_id = ", i_d = gcp_conf.get('xxx')"
        if not _req_data.uri_id.isdigit():
            uri_id_pre_fix = '{gcp_conf.get("xxx")}'
            uri_id_postfix = '/'.join(_req_data.uri_id.split('/')[1:])
            uri_id = f", i_d = f'{uri_id_pre_fix}/{uri_id_postfix}'"

    _url_key = 'lock' if 'lock' in url else method
    is_del = ''
    is_del_import = ', is_del'
    if 'del_' in case_id or 'lock_' in case_id or 'delete_' in case_id:
        is_del = "\n    @pytest.mark.skipif(is_del(), reason='根据配置决定是否执行删除')"

    # 用例方法 :
    pytest_test_code = f"""
    # {case_id} : ( {title} )
    @pytest.mark.parametrize('case_data', gcp_data.get('{sheet_name}', '{case_id}')){is_del}
    def test_{case_id}(self, case_data: ExcelData, please_revise_this_api: GcpApi):
        \"\"\" {title} \"\"\"
        
        # 准备数据 : ( gcp_conf )
        case_data.data['xxx'] = gcp_conf.get('xxx')

        # 调用接口 : ( 一般将 api 创建放在 conftest 中, 这里直接引用, 会比较方便 )
        # gcp_user_api / web_pi_api / web_crc_api / web_sn_api / app_pi_api / app_crc_api / app_sn_api / app_sub_api
        # gcp_user_son_api / web_pi_son_api / web_crc_son_api / web_sn_son_api / app_pi_son_api / app_crc_son_api / app_sn_son_api / app_sub_son_api
        # GcpUserApi() / WebPiApi() / WebCrcApi() / WebSnApi() / AppPiApi() / AppCrcApi() / AppSnApi() / AppSubApi()
        # GcpUserSonApi() / WebPiSonApi() / WebCrcSonApi() / WebSnSonApi() / AppPiSonApi() / AppCrcSonApi() / AppSnSonApi() / AppSubSonApi()
        _res = _please_revise_this_api.call_assert(case_data{uri_id})

        # 数据处理 : ( gcp_extract )( json2set / key2set 均会返回提取结果 )
        _value1 = gcp_extract.key2set('write_key', _res, 'result', 'key1', 'key2')  # key='write_key', target=_res, keys=('result', 'key1', 'key2')
        _value2 = gcp_extract.json2set(key='write_key', target=_res, json_expression='$..key2')
    """

    # 用例类 :
    pytest_class_code = f"""
import allure
import pytest

# -> GCP P C 临研管理员 : GcpUserApi()  ------------------------------->  (管理员)
# -> GCP P C 的各个用户 : WebPiApi, WebCrcApi, WebSnApi --------------->  (研究员)(协调员)(研究护士)
# -> GCP App 的各个用户 : AppPiApi, AppCrcApi, AppSnApi, AppSubApi  --->  (研究员)(协调员)(研究护士)(受试者)
from cases_gcp.common_gcp import *
from common import ExcelData{is_del_import}
    
    
@allure.epic('GCP临研中心')
@allure.feature('00X_{model}_')
class TestCaseXx:
    \"\"\" {model} \"\"\"
    
    {pytest_test_code}
"""

    return {
        'pytest_class_code': pytest_class_code,
        'pytest_test_code': pytest_test_code,
        'case_id': case_id,
        'api_name': api_name,
        'model': model,
        'title': title,
        'host': host,
        'url': url,
        'method': method,
        'data': data,
        'sheet_name': sheet_name
    }


# excel 数据写入 :
def write_excel(excel_path: str, excel_data: dict, excel_sheet: str = None):
    """
    加载 Excel (excel_path)
    将 excel_data 写入 Excel 中
    :param excel_path: Excel 文件路径
    :param excel_data: Excel 数据, json 格式
    :param excel_sheet: Excel Sheet 页
    :return:
    """
    if not excel_path or not excel_data:
        return {'status': '0', 'msg': 'Excel文件或写入数据为空, 请检查'}
    if not excel_sheet:
        return {'status': '0', 'msg': 'Sheet 页都没指定, 往哪儿写入哇'}
    if excel_path and excel_data:
        if excel_sheet:
            try:
                wb = openpyxl.load_workbook(filename=excel_path)
                try:
                    sheet = wb[excel_sheet]
                except KeyError as e:
                    return {'status': '0', 'msg': f'你瞎的吗, Sheet页都写错了 : {e}'}

                # 检查 case_id 是否重复
                existing_case_ids = {sheet.cell(row=row_id, column=1).value for row_id in range(3, sheet.max_row + 1)}
                case_id = excel_data.get('case_id')
                if case_id in existing_case_ids:
                    return {'status': '0', 'msg': '存在重复 case_id，数据未写入'}

                # 表头 :
                headers = [cell.value for cell in sheet[2]]

                # 写入的行号 :
                write_row_id = None
                for row_id, row in enumerate(sheet.iter_rows(min_row=3, values_only=True), start=3):
                    current_row_empty = all(cell is None for cell in row)
                    if current_row_empty:
                        write_row_id = row_id
                        break
                if write_row_id is None:
                    write_row_id = sheet.max_row + 1

                # 写入数据 :
                for column_id, header in enumerate(headers, start=1):
                    cell_value = excel_data.get(header)
                    if cell_value is not None:
                        sheet.cell(row=write_row_id, column=column_id).value = cell_value

                # 保存和关闭 :
                wb.save(excel_path)
                wb.close()
            except PermissionError as e:
                # 权限异常比较特殊，遇到这个问题，通常是 Excel 文件在本机处于打开状态
                # 因此，出现权限异常时，可以通过 Js 方法复制 Excel 数据
                # 既然本机打开了 Excel， 那就复制出来，提示粘贴即可
                # 所以，这里的 status 为 1 是有特殊含义的，后续更新此处代码，请在需要 Js 复制的场景让 status 为 1
                return {'status': '1', 'msg': f'写入失败, 请关闭文件后重试!{e}'}
            except FileNotFoundError as e:
                return {'status': '0', 'msg': f'文件不存在, 请检查 : {e}'}
            except InvalidFileException as e:
                return {'status': '0', 'msg': f'你瞎的吗, 你选的啥文件, 请选择 xlsx 文件 : {e}'}
            else:
                return {'status': '2', 'msg': '写入成功'}


if __name__ == '__main__':
    _excel_path = r'C:\Users\yl\Desktop\test\api_test_gcp_v001.xlsx'
    _excel_data = {'case_id': 'demo_002', 'name': '1', 'model': '2', 'rank': '3', 'host': 'gcp'}
    # _excel_sheet = 'GCP分享'
    _excel_sheet = 'GCP分享1111'
    # print(write_excel(excel_path=_excel_path, excel_data=_excel_data, excel_sheet=_excel_sheet))
